package com.db.utils.okhttp;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.*;
import java.util.Map;

import com.db.utils.Util;

public class HttpHelper {

    //public static final String clientSdk = "android4.30.1";//之前是"android:4.33.1"？？？？
    public static final String userAgent = "Mozilla/6.0 (Linux; Android 6.0; Nexus 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36";
    //public static final String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36";
    public static final String userAgent2 = "Mozilla/5.0 (Linux; Android 11; moto g(8) Build/RPJS31.Q4U-47-35-17; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36";

    public static final String userAgent_ios_14_2 = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1";
    public static final String userAgent_ios_15_7_6 = "Mozilla/5.0 (iPhone; CPU iPhone OS 15_7_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.4 Mobile/15E148 Safari/604.1";
    public static final String userAgent_CFNetwork_15_7_6 = "CFNetwork/1335.0.3.2 Darwin/21.6.0";//v15.7.6
    public static final String userAgent_CFNetwork_14_2 = "CFNetwork/1206 Darwin/20.1.0";//v14.2
    //public static String gps_adid = UUID.randomUUID().toString();
    //public static String android_uuid = UUID.randomUUID().toString();
/*
    public static String onGet(String url) {
    	String result = "";
        try {
        	HttpURLConnection connection = newHttpURLConnection(url);
            connection.setRequestMethod("GET");
            connection.setInstanceFollowRedirects(false);// 默认true, 不能处理大于4次的重定向
            if (userAgent != null) {
                connection.setRequestProperty("User-Agent", userAgent);
            }
            result = readConnectionResponse(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
*/

    public static String doGet(String url, Map<String, String> params, Map<String, String> headers, String proxy) {
        String result = "";
        try {
            if (params != null && !params.isEmpty()) {
                url = url + "?" + generatePOSTBodyString(params);
            }

            //System.out.println("## luo get url: " + url);
            HttpsURLConnection connection = newHttpsURLConnection(url, proxy);
            connection.setRequestMethod("GET");
            if (headers != null) {
                for (String key : headers.keySet()) {
                    connection.addRequestProperty(key, headers.get(key));
                    //httpGet.addHeader(key, headers.get(key));
                }
            }
            //if(authorizationHeader != null) {
            //	connection.setRequestProperty("Authorization", authorizationHeader);
            //}

            result = readConnectionResponse(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String doPost(String url, Map<String, String> params, Map<String, String> headers, String proxy) {
        String result = "";
        DataOutputStream dataOutputStream = null;
        try {
            //url = Util.formatString("%s%s", url, path);
            HttpsURLConnection connection = newHttpsURLConnection(url, proxy);
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);
            if (headers != null) {
                for (String key : headers.keySet()) {
                    connection.addRequestProperty(key, headers.get(key));
                    //httpGet.addHeader(key, headers.get(key));
                }
            }
            //if(authorizationHeader != null) {
            //	connection.setRequestProperty("Authorization", authorizationHeader);
            //}

            String postBodyString = generatePOSTBodyString(params);

            dataOutputStream = new DataOutputStream(connection.getOutputStream());
            dataOutputStream.writeBytes(postBodyString);
            result = readConnectionResponse(connection);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (dataOutputStream != null) {
                    dataOutputStream.flush();
                    dataOutputStream.close();
                }
            } catch (final IOException ioException) {
                ioException.printStackTrace();
            }
        }
        return result;
    }

    private static String readConnectionResponse(final HttpURLConnection connection) {
        final StringBuilder responseStringBuilder = new StringBuilder();
        Integer responseCode = 0;//null
        String responseString = "";

        // connect and read response to string builder
        try {
            connection.connect();
            responseCode = connection.getResponseCode();
            final InputStream inputStream;

            if (responseCode.intValue() >= 400) {
                inputStream = connection.getErrorStream();
            } else {
                inputStream = connection.getInputStream();
            }

            final InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            final BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String line;
            while ((line = bufferedReader.readLine()) != null) {
                responseStringBuilder.append(line);
            }
        } catch (final IOException ioException) {
            ioException.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        //        if (responseStringBuilder.length() == 0) {
        //            //logger.error("Empty response string buffer");
        //            return responseCode;
        //        }
        //
        //        if (responseCode == 429) {
        //            //logger.error("Too frequent requests to the endpoint (429)");
        //            return responseCode;
        //        }

        // extract response string from string builder
        responseString = responseStringBuilder.toString();

        return responseString;
    }

    private static HttpURLConnection newHttpURLConnection(String url) throws Exception {
        URL u = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) u.openConnection();
        connection.setConnectTimeout(60 * 1000);
        connection.setReadTimeout(60 * 1000);
        return connection;
    }

    private static HttpsURLConnection newHttpsURLConnection(String url, String proxy) throws Exception {
        URL u = new URL(url);
        HttpsURLConnection connection = (HttpsURLConnection) u.openConnection(createProxy(proxy, 1));
        connection.setConnectTimeout(60 * 1000);
        connection.setReadTimeout(60 * 1000);
        return connection;
    }

    private static void applyConnectionOptions(final HttpURLConnection connection, final String clientSdk) {
        connection.setRequestProperty("Client-SDK", clientSdk);
        connection.setConnectTimeout(60 * 1000);
        connection.setReadTimeout(60 * 1000);
    }

    public static String generatePOSTBodyString(final Map<String, String> params) {
        if (params.isEmpty()) {
            return null;
        }

        StringBuilder sbParams = new StringBuilder();
        final StringBuilder postStringBuilder = new StringBuilder();

        //if (params.containsKey("gps_adid"))
        //    params.put("gps_adid", gps_adid);
        //if (params.containsKey("android_uuid"))
        //    params.put("android_uuid", android_uuid);
        for (final Map.Entry<String, String> entry : params.entrySet()) {
            try {
                String encodedName = URLEncoder.encode(entry.getKey(), Util.ENCODING);
                String value = entry.getValue();
                String encodedValue = value != null ? URLEncoder.encode(value, Util.ENCODING) : "";
                if (encodedName.equals("attribution_token")) {
                    encodedValue = value;
                }
                postStringBuilder.append(encodedName);
                postStringBuilder.append("=");
                postStringBuilder.append(encodedValue);
                postStringBuilder.append("&");

                sbParams.append("\r\n").append(entry.getKey()).append("=").append(entry.getValue());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //System.out.println("#luo sbParams: " + sbParams);

        // delete last added &
        if (postStringBuilder.length() > 0 && postStringBuilder.charAt(postStringBuilder.length() - 1) == '&') {
            postStringBuilder.deleteCharAt(postStringBuilder.length() - 1);
        }
        return postStringBuilder.toString();
    }


    public static String getReferrer(String url, Map<String, String> params, Map<String, String> headers, String proxy) {
        try {
            System.out.println("## luo getReferrer: " + url);

            url = url.replace("|", "%7C");
            url = url.replace("{", "%7B");
            url = url.replace("}", "%7D");
            url = url.replace(" ", "%20");

            HttpURLConnection urlConnection = getConnection(url, proxy);
            if (headers != null) {
                for (String key : headers.keySet()) {
                    //builder.addHeader(key, headers.get(key));
                    urlConnection.setRequestProperty(key, headers.get(key));
                }
            }
            System.out.println("#luo getReferer2: " + urlConnection.getURL());

            urlConnection.connect();
            String url302 = null;
            int responseCode = urlConnection.getResponseCode();
            System.out.println("#luo responseCode: " + responseCode);
            if (responseCode == 301 || responseCode == 302) {
                url302 = urlConnection.getHeaderField("Location");
                if (url302 == null || url302.length() < 2) {
                    url302 = urlConnection.getHeaderField("location"); //临时重定向和永久重定向location的大小写有区分
                }
                if (!(url302.startsWith("http://") || url302.startsWith("https://") || url302.startsWith("market:"))) { //某些时候会省略host，只返回后面的path，所以需要补全url
                    URL originalUrl = new URL(url);
                    url302 = originalUrl.getProtocol() + "://" + originalUrl.getHost() + ":" + originalUrl.getPort() + url302;
                }
            } else if (responseCode == 200) {
                try {
                    //HttpEntity httpEntity = response.getEntity();
                    String resultString = urlConnection.getResponseMessage();
                    //System.out.println("#luo resultString: " + resultString);
                    if (resultString != null && resultString.contains("url=")) {
                        resultString = resultString.substring(resultString.indexOf("url=") + 4);
                        url302 = resultString.substring(0, resultString.indexOf("\""));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (url302 == null || url302.equals("")) {
                return url;//可能异常了
            }
            if (url302.startsWith("market:") || url302.startsWith("https://play.google.com")) {
                System.out.println("#luo getReferrer: " + url302);
                return url302;
            }
            return getReferrer(url302, params, headers, proxy);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 获取GET连接
     *
     * @param strUrl 连接的地址
     * @return 连接对象
     * @throws IOException
     */
    public static HttpURLConnection getConnection(String strUrl, String proxyInfo) throws IOException {
        URL url = new URL(strUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection(createProxy(proxyInfo, 1));
        connection.setInstanceFollowRedirects(false); //设置成false，则需要自己从http reply中分析新的url自己重新连接。
        connection.setConnectTimeout(15 * 1000);
        connection.setReadTimeout(15 * 1000);
        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setRequestProperty("User-Agent", userAgent);
        connection.setRequestProperty("Content-type", "application/json;charset=UTF-8");
        return connection;
    }

//    public static class Result {
//        public int code;
//        public String res;
//    }

    public static Proxy createProxy(String proxy, int type) {
        String proxyHost = null;
        Integer proxyPort = null;
        String proxyUsername = null;
        String proxyPassword = null;
        //String proxyProtocol = "http";

        if (proxy != null) {
            String[] proxyArr = proxy.split(":");
            if (proxyArr.length > 1) {
                proxyHost = proxyArr[0];
                proxyPort = Integer.valueOf(proxyArr[1]);
            }
            if (proxyArr.length > 3) {
                proxyUsername = proxyArr[2];
                proxyPassword = proxyArr[3];
            }
        }
        final String userName = proxyUsername == null ? "" : proxyUsername;
        final String userPassword = proxyPassword == null ? "" : proxyPassword;
        Proxy newProxy = new Proxy(type == 1 ? Proxy.Type.SOCKS : Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
        Authenticator.setDefault(new Authenticator() {
            private PasswordAuthentication authentication = new PasswordAuthentication(userName, userPassword.toCharArray());

            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                System.out.println("auth:" + getRequestingHost());
                return authentication;
            }
        });
        return newProxy;
    }

}
